package com.idea.relax.datascope.aron;

import com.idea.relax.datascope.constant.SqlConstant;
import com.idea.relax.tool.core.Func;
import lombok.AllArgsConstructor;
import org.apache.ibatis.mapping.BoundSql;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;

/**
 * @className: DataScopeHandler
 * @description:
 * @author: salad
 * @date: 2023/5/3
 **/
@AllArgsConstructor
public class DataScopeHandler implements IDataScopeHandler {


	private final List<IDataAuthValueProvider> providers;

	@Override
	public String conditionSql(DataAuthModel model, BoundSql boundSql, String targetSql) {
		if (model.getCode().length() == 0) {
			throw new RuntimeException("请声明一个code值");
		}
		//SQL连接符 and or
		Condition[] condition = model.getCondition();
		//where SQL
		String[] value = model.getValue();
		if (condition.length > 1 && condition.length != value.length) {
			throw new RuntimeException("");
		}
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < value.length; i++) {
			String key = value[i];
			List<String> place = PlaceholderUtil.find(key);
			if (place.size() > 1) {
				throw new RuntimeException("不支持多个占位符");
			}
			if (place.size() == 1) {
				//使用正则优化
//				String placeholderVal = key.substring(key.indexOf("{") + 1, key.indexOf("}"));
				String placeholderVal = place.get(0);
				IDataAuthValueProvider provider = providers.stream()
					.filter(item -> item.codeSupport().equals(model.getCode()))
					.findFirst().orElseThrow(() -> new RuntimeException("未获取到对应的参数提供者"));
				Object providerValue = provider.getValue(model.getCode(), placeholderVal);
				stringBuilder.append(SqlConstant.SCOPE).append(".");
				if (providerValue instanceof List) {
					List<?> list = (List<?>) providerValue;
					String sql = StringUtil.format(key, Func.join(list));
					stringBuilder.append(sql);
				} else if (providerValue.getClass().isArray()) {
					String sql = StringUtil.format(key, Func.join(Arrays.asList(providerValue)));
					stringBuilder.append(sql);
				} else {
					String sql = StringUtil.format(key, providerValue);
					stringBuilder.append(sql);
				}
			} else {
				stringBuilder.append(value[i]);
			}
			if (i < value.length - 1) {
				stringBuilder.append(condition.length == 1 ? condition[0].getValue() : condition[i].getValue());
			}

		}
		//scope.isOpen = 1 and scope.userId in (1,2,3,4)
		String sql = stringBuilder.toString();
		return String.format(SqlConstant.SELECT_PREFIX.concat(SqlConstant.WHERE), targetSql, sql);
	}

}
